//
//  WmcDateManager.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/3/7.
//

import UIKit
import Kronos
import YPBedrock
import YPNetwork
import Foundation
import NSObject_Rx

// MARK: - [WmcDateManager.TimeState]

extension WmcDateManager {
    /// 时间状态
    enum TimeState {
        case real
        case notReal
    }
}

// MARK: - [WmcDateManager]

class WmcDateManager: NSObject {
    // Public

    /// 单例实例化
    public static let shared: WmcDateManager = {
        let manager = WmcDateManager()
        return manager
    }()

    // Internal

    /// 可订阅当前网络时间
    var networkDate: BehaviorRelay<Date?> = .init(value: Date())

    /// 当前网络时间的状态
    var timeState: BehaviorRelay<TimeState> = .init(value: .notReal)

    /// 记录时间
    var timerDate: Date = .init()

    /// 是否停止时间
    var isStopDate: Bool = false

    /// 配置
    func config() {
        // 应用回到前台
//        WmcAppStateManager.shared.appEnterForeground.subscribe(onNext: { [weak self] in
//            guard let weakSelf = self,
//                  !weakSelf.isStopDate else { return }
//            weakSelf.requestDate()
//        }).disposed(by: rx.disposeBag)
//
//        // 监听网络状态
//        YPNetworkReachability.monitoring().subscribe(onNext: { [weak self] type in
//            guard let weakSelf = self,
//                  !weakSelf.isStopDate else { return }
//            weakSelf.requestDate()
//        }).disposed(by: rx.disposeBag)
        Clock.sync()
    }

    func stopDate() {
        isStopDate = true
    }

    /// 请求时间
    func requestDate() {
        isStopDate = false
        if let ntpDate = Clock.now {
            networkDate.accept(ntpDate + 8.yp.hour)
            timeState.accept(.real)
        } else {
            networkDate.accept(Date() + 8.yp.hour)
            timeState.accept(.notReal)
        }

        // 开始自动算时间
        startLink()

//        log("正在获取网络时间...")
//        YPSession.Request(url: "http://www.baidu.com",
//                          method: .get,
//                          timeoutInterval: 4) { [weak self] data, response in
//            guard let weakSelf = self else { return }
//            let fomat = DateFormatter()
//            // 同步GMT时间
//            fomat.timeZone = TimeZone.YP.CreateOptional(identifier: .gmt(.GMT))
//            fomat.locale = Locale(identifier: "en_US_POSIX")
//            fomat.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
//            guard let httpResponse = response as? HTTPURLResponse,
//                  let fieldsDateStr = (httpResponse.allHeaderFields["Date"] as? String),
//                  let date = fomat.date(from: fieldsDateStr) else {
//                weakSelf.log("获取网络时间失败")
//                syncLocationDate(weakSelf)
//                return
//            }
//            weakSelf.log("成功获取网络时间: \(fieldsDateStr)")
//            // 计算时差
//            let standardDate = date + 8.yp.hour
//            weakSelf.log("计算本地标准时间: \(standardDate)")
//            // 获取标准时间
//            weakSelf.timerDate = standardDate
//            weakSelf.networkDate.accept(standardDate)
//            // 开始自动算时间
//            weakSelf.startLink()
//            weakSelf.timeState.accept(.real)
//        } failure: { [weak self] err, response in
//            guard let weakSelf = self else { return }
//            weakSelf.log("获取网络时间失败")
//            syncLocationDate(weakSelf)
//        }
//
//        func syncLocationDate(_ base: WmcDateManager) {
//            base.log("正在获取本地时间...")
//            // 获取系统时间
//            let systemDate = Date() + 8.yp.hour
//            base.timerDate = systemDate
//            base.networkDate.accept(systemDate)
//            // 开始自动算时间
//            base.startLink()
//            base.timeState.accept(.notReal)
//        }
    }

    // Fileprivate

    /// 开始计时
    fileprivate func startLink() {
        guard !isStopDate else { return }
        stopLink()
        YPGCD.Main { [weak self] in
            guard let weakSelf = self else { return }
            weakSelf.log("正在自动计算时间...")
            weakSelf.link = CADisplayLink(target: weakSelf, selector: #selector(weakSelf.linkRun))
            weakSelf.link?.preferredFramesPerSecond = 1
            weakSelf.link?.isPaused = false
            weakSelf.link?.add(to: .current, forMode: .default)
            if let date = weakSelf.networkDate.value {
                weakSelf.log("时间已同步: \(date)")
            }
        }
    }

    @objc
    fileprivate func linkRun() {
//        guard let nowDate = networkDate.value else { return }
//        let newDate = nowDate + 1.yp.second
//        networkDate.accept(newDate)
        let newDate: Date
        if let ntpDate = Clock.now {
            newDate = ntpDate
            timeState.accept(.real)
        } else {
            newDate = Date()
            timeState.accept(.notReal)
        }
        networkDate.accept(newDate + 8.yp.hour)
        // 每隔一段时间更新时间
//        if timeCount >= timeUpdateCount {
//            requestDate()
//            timeCount = 0
//        } else {
//            timeCount += 1
//        }
    }

    /// 停止计时
    fileprivate func stopLink() {
        YPGCD.Main { [weak self] in
            guard let weakSelf = self else { return }
            weakSelf.link?.isPaused = true
            weakSelf.link?.invalidate()
            weakSelf.link = nil
        }
    }

    /// 日志系统
    fileprivate func log(_ log: String) {
        WmcLogManager.DebugLog(type: .dateManager, log: log)
    }

    // Private

    /// 计时器
    private var link: CADisplayLink?

    private let timeUpdateCount = 1
    private var timeCount = 0
}
